package com.doit.day04

import java.time.{LocalDateTime, ZoneOffset}
import java.time.format.DateTimeFormatter
import scala.io.Source

/*
   1_1193_5_978300760
   1_661_3_978302109
   1_914_3_978301968
   1_3408_4_978300275
   1_2355_5_978824291
   1_1197_3_978302268
   1_1287_5_978302039
   1_2804_5_978300719
   1_594_4_978302268
   1_919_4_978301368
   1_595_5_978824268
 */
object _01_昨日练习 {
  def main(args: Array[String]): Unit = {

    val ratings: Array[String] = Source.fromFile("C:\\Users\\34650\\Desktop\\课程资料\\资料\\ratings.txt")
      .getLines()
      .toArray

    val id_score_date: Array[(String, Int, String)] = ratings.map(line => {
      val arr: Array[String] = line.split("_")
      val movie_id: String = arr(1)
      val score: Int = arr(2).toInt
      val timeStamp: String = arr(3)
      val date: String = ts2Date(timeStamp)
      //日期转换 将一个s级别的时间戳转换成年月日
      (movie_id, score, date)
    })


    // (1193 ,5 , 2000-01-01 )
    // (661  ,3 , 2000-01-02 )
    // (914  ,3 , 2000-01-03 )
    // (3408 ,4 , 2000-01-01 )
    // (2355 ,5 , 2000-01-02 )
    // (1197 ,3 , 2000-01-01 )
    // (1287 ,5 , 2000-01-02 )
    // (2804 ,5 , 2000-01-03 )
    // (594  ,4 , 2000-01-04 )
    // (919  ,4 , 2000-01-03 )
    // (595  ,5 , 2000-01-04 )


    //    对日期进行分组：
    val grouped: Map[String, Array[(String, Int, String)]] = id_score_date.groupBy(_._3)


    // grouped的数据就长这样
    // 2000-01-01  Array((1193 ,5 , 2000-01-01 ),(3408 ,4 , 2000-01-01 ),(1197 ,3 , 2000-01-01 ))
    // 2000-01-02  Array((661  ,3 , 2000-01-02 ),(2355 ,5 , 2000-01-02 ),(1287 ,5 , 2000-01-02 ))
    // 2000-01-03  Array((914  ,3 , 2000-01-03 ),(2804 ,5 , 2000-01-03 ),(919  ,4 , 2000-01-03 ))
    // 2000-01-04  Array((594  ,4 , 2000-01-04 ),(595  ,5 , 2000-01-04 ))

    //    统计每一天电影的个数
    val tuples: Array[(String, Double, Array[(String, Double)])] = grouped.toArray.map(tp => {
      //map中的key 也就是日期
      val date = tp._1
      //map的value 也就是每一天对应的被评分过的电影id和电影评分
      val arr = tp._2

      //求电影的个数==> 有可能会出现这种情况==》 同一天，同一部电影被多个人评分过
      val cnt = arr.map(_._1).toSet.size //.distinct.size()

      // 每部电影的平均分是多少
      // 总分数/总分个数
      val map: Map[String, Array[(String, Int, String)]] = arr.groupBy(_._1)
      val arr1: Array[(String, Array[(String, Int, String)])] = map.toArray

      //数据长什么样
      // 1193  Array((1193 ,5 , 2000-01-01 ),(1193 ,4 , 2000-01-01 ),(1193 ,3 , 2000-01-01 ))
      // 3408  Array((3408 ,4 , 2000-01-01 ),(3408 ,4 , 2000-01-01 ),(3408 ,4 , 2000-01-01 ))
      // 1197  Array((1197 ,3 , 2000-01-01 ),(1197 ,3 , 2000-01-01 ),(1197 ,3 , 2000-01-01 ))

      val id_avg = arr1.map(tp => {
        val movie_id = tp._1
        val value1: Array[(String, Int, String)] = tp._2

        val value: Array[(String, Int, String)] = tp._2
        val score_avg = (value.map(_._2).sum.toDouble / tp._2.size).formatted("%.2f").toDouble


        (movie_id, score_avg)
      })


      //再把每个电影的平均分全部加起来/电影个数
      val total_avg = (id_avg.map(_._2).sum.toDouble / cnt).formatted("%.2f").toDouble

      (date, total_avg, id_avg)

    })

  /*  tuples.sortBy(_._1)
      .take(10)
      .foreach(println)*/

    /*
    //这里面不是有一个时间戳吗？按照天进行分组，求得每天有多少部电影被评分，
    // 每部电影的平均分是多少  再把每个电影的评分全部加起来/电影个数
    /*
       将时间戳格式化成日期 年月日即可
       1_919_4_2000-01-01
       1_595_5_2000-01-01
       1_595_5_2000-01-01
       对日期进行groupBy ==》 Map[2000-01-01 ,Array[1_595_5_2000-01-01]]
     */


    //就是将上面一行行的内容转变成数组，数组里面放的是三元元祖，也就是 id 分数 日期
    val id_score_date: Array[(String, Int, String)] = ratings.map(line => {
      val arr: Array[String] = line.split("_")
      val movie_id: String = arr(1)
      val score: Int = arr(2).toInt
      val timeStamp: String = arr(3)
      val date: String = ts2Date(timeStamp)
      //日期转换 将一个s级别的时间戳转换成年月日
      (movie_id, score, date)
    })


    //对日期分组
    val grouped :Map[String,Array[(String, Int, String)]]= id_score_date.groupBy(_._3)


    //对分完组的结果进行求平均分
    val tuples: Array[(String, Double, Map[String, Double])] = grouped.toArray.map(tp => {
      val date: String = tp._1
      val arr: Array[(String, Int, String)] = tp._2
      //将原来放着电影名称，评分，日期的arr转变成只有电影id的数组，然后对数组中的电影id进行去重之后取个数
      //      val movie_count: Int = arr.map(_._1).distinct.size
      //      每部电影的平均分是多少  再把每个电影的平均分评分全部加起来/电影个数
      //按照电影id进行groupBy
      val id_res: Map[String, Array[(String, Int, String)]] = arr.groupBy(_._1)
      //电影的个数
      val movie_count: Int = id_res.size
      //每个电影  电影的平均分
      val id_avg: Map[String, Double] = id_res.map(tp => {
        val movie_id: String = tp._1
        //每个电影  电影的平均分
        (movie_id, (tp._2.map(_._2).sum.toDouble / tp._2.size).formatted("%.2f").toDouble)
      })

      //再把每个电影的平均分评分全部加起来/电影个数
      val avg: Double = (id_avg.toArray.map(_._2).sum / movie_count).formatted("%.2f").toDouble

      (date, avg,id_avg)
    })

    tuples.sortBy(_._1)
      .take(10)
      .foreach(println)

     */


    //按照天进行分组，求得每天有多少人评论电影，总平均分
    val user_score_date: Array[(String, Int, String)] = ratings.map(line => {
      val arr: Array[String] = line.split("_")
      val user_id: String = arr(0)
      val score: Int = arr(2).toInt
      val timeStamp: String = arr(3)
      val date: String = ts2Date(timeStamp)
      //日期转换 将一个s级别的时间戳转换成年月日
      (user_id, score, date)
    })


    user_score_date.groupBy(_._3)
      .toList
      .map(tp=>{
        val date: String = tp._1
        val cnt: Int = tp._2.map(_._1).distinct.size
        val avg = (tp._2.map(_._2).sum.toDouble/tp._2.size).formatted("%.2f").toDouble

        (date,cnt,avg)
      })
      .sortBy(_._1)
      .take(10)
      .foreach(println)







  }


  //日期转换的方法
  def ts2Date(timeStamp: String) = {
    val offset: ZoneOffset = ZoneOffset.ofTotalSeconds(3600 * 8)
    val dateTime = LocalDateTime.ofEpochSecond(timeStamp.toInt, 0, offset)
    val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    dateTime.format(formatter)
  }
}
